home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
Games
/
connx-1.0
/
commun.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-05
|
6KB
|
323 lines
/*
* socket package - supports both unix scoket files
* and TCPIP sockets. Use -DTCPIP when compiling if
* TCPIP sockets are desired.
*/
#include "commun.h"
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/signal.h>
#include <sys/uio.h>
#include <sys/time.h>
#ifdef AIX
#include <sys/select.h>
#endif
#ifdef TCPIP
#include <netinet/in.h>
#include <arpa/inet.h>
#else
#include <sys/un.h>
#endif
/****************************************************************************/
#ifdef DEBUG
#define PRINTF(x) printf(x)
#else
#define PRINTF(x) ;
#endif
/*
* open server socket to be used to accept
* client connections
*/
int
server_open_socket (int *sockfd)
{
/* setup socket address */
#ifdef TCPIP
struct sockaddr_in src;
src.sin_addr.s_addr = INADDR_ANY;
src.sin_port = SOCK_PORT;
#else
struct sockaddr_un src;
unlink (SOCK_FILE);
src.sun_family = AF_UNIX;
strcpy (src.sun_path, SOCK_FILE);
#endif
/* broken pipes are ignored. */
signal (SIGPIPE, SIG_IGN);
if ((*sockfd = socket (
#ifdef TCPIP
AF_INET,
#else
AF_UNIX,
#endif
SOCK_STREAM, 0)) < 0)
{
printf ("socket failure errno=%d\n", errno);
return -1;
}
if (bind (*sockfd, (struct sockaddr *) &src, sizeof (src)) < 0)
{
printf ("bind failure errno=%d\n", errno);
return -1;
}
if (listen (*sockfd, MAX_CONN) < 0)
{
printf ("listen failure errno=%d\n", errno);
return -1;
}
return 0;
}
/****************************************************************************/
/*
* server accepts connections from client
*/
int
server_accept_connection (int sockfd, msg_conn * conns)
{
int fromlen;
int new_sock;
/* socket address */
#ifdef TCPIP
struct sockaddr_in fromend;
#else
struct sockaddr_un fromend;
#endif
fromlen = sizeof fromend;
if (conns->number_of_conn == MAX_CONN)
{
printf ("maximum number of connections\n");
return -1;
}
new_sock = accept (sockfd, (struct sockaddr *) &fromend, &fromlen);
if (new_sock != -1)
{
conns->conns[conns->number_of_conn++] = new_sock;
return 0;
}
else
return -1;
}
/****************************************************************************/
/*
* client opens connection with server
*/
int
client_open_connection (int *sockfd, char *name)
{
/* use name to find TCPIP address of server */
#ifdef TCPIP
struct sockaddr_in src;
struct hostent *ph;
int len;
long address;
if (isdigit (name[0]))
{
if ((address = inet_addr (name)) == -1)
{
printf ("invalid host name %s\n",name);
return -1;
}
src.sin_addr.s_addr = address;
src.sin_family = AF_INET;
}
else if ((ph = gethostbyname (name)) == NULL)
{
printf ("invalid host name %s\n",name);
return -1;
}
else
{
src.sin_family = ph->h_addrtype;
bcopy (ph->h_addr, (char *) &src.sin_addr, ph->h_length);
}
src.sin_port = SOCK_PORT;
#else
/* use socket file to communicate with server */
struct sockaddr_un src;
src.sun_family = AF_UNIX;
strcpy (src.sun_path, SOCK_FILE);
#endif
/* ignore broken pipes */
signal (SIGPIPE, SIG_IGN);
if ((*sockfd = socket (
#ifdef TCPIP
AF_INET,
#else
AF_UNIX,
#endif
SOCK_STREAM, 0)) < 0)
{
printf ("socket errno=%d\n", errno);
return -1;
}
if (connect (*sockfd, (struct sockaddr *) &src, sizeof (src)) < 0)
{
printf ("connect errno=%d\n", errno);
return -1;
}
return 0;
}
/****************************************************************************/
/*
* send a message across a socket
*/
int
send_message (int *sock, int type, int size, char *msg)
{
struct iovec vec[3];
if (*sock == -1)
return -1;
vec[0].iov_base = (char *) &type;
vec[0].iov_len = sizeof (int);
vec[1].iov_base = (char *) &size;
vec[1].iov_len = sizeof (int);
vec[2].iov_base = msg;
vec[2].iov_len = size;
if (writev (*sock, vec, 3) != (size + (2 * sizeof (int))))
{
PRINTF ("close on send\n");
close_socket (sock);
return -1;
}
return 0;
}
/****************************************************************************/
/*
* read a message from a socket
*/
int
read_message (int *sock, gen_msg * msg_receive)
{
int typ, len, rc;
if (*sock == -1)
return -1;
/* read message type */
rc = read (*sock, &typ, sizeof (int));
if (rc != sizeof (int))
{
PRINTF ("close on read\n");
close_socket (sock);
return -1;
}
/* read message length */
if (read (*sock, &len, sizeof (int)) != sizeof (int))
{
PRINTF ("close on read\n");
close_socket (sock);
return -1;
}
msg_receive->msg_type = typ;
msg_receive->msg_length = len;
/* read message data */
if (len > 0)
if (read (*sock, msg_receive->msg, len) != len)
{
PRINTF ("close on read\n");
close_socket (sock);
return -1;
}
return 0;
}
/*****************************************************************************/
/*
* check to see if a socket has closed (sent EOF)
*/
int
check_status (int *sock)
{
int rc, buf;
struct fd_set readfs;
struct timeval notimeout;
if (*sock == -1)
return -1;
notimeout.tv_sec = 0;
notimeout.tv_usec = 0;
FD_ZERO (&readfs);
FD_SET (*sock, &readfs);
if ((rc = select ((*sock) + 1, &readfs, NULL, NULL, ¬imeout)) != 0)
{
rc = recv (*sock, (char *) &buf, sizeof (int), MSG_PEEK);
if (rc <= 0) /* socket closed */
{
close_socket (sock);
return -1;
}
}
return 0;
}
/****************************************************************************/
/*
* close a socket
*/
int
close_socket (int *sock)
{
if (*sock != -1)
{
close (*sock);
*sock = -1;
}
}
/****************************************************************************/